

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StreamCorruptedException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

public class ClientConnection {
	
	static Socket connectionSocket;
	static Socket connectionSocketPS;
	
	/**
	 * To create Socket object, for both Server and Client
	 * @param ipAddress
	 * @param port
	 */
	public static boolean openConnection(String ipAddress,int port){
		boolean ret = true;
		//System.out.println("ClientConnection.openConnection("+ipAddress+","+port+")");
		try {
			connectionSocket = new Socket(ipAddress, port);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			ret = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			ret = false;
		}
		
		return ret;
	}
	
	public static boolean openConnectionPS(String ipAddress,int port){
		boolean ret = true;
		
		try {
			connectionSocketPS = new Socket(ipAddress, port);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			ret = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			ret = false;
		}
		
		return ret;
	}
	
	public static Socket openAndGetConnection(String ipAddress,int port){
		
		try {
			connectionSocket = new Socket(ipAddress, port);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			return null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			return null;
		}
		
		return connectionSocket;
	}
	
	/**
	 * Read the received message for Server
	 * @param port
	 * @return received message or empty message
	 * @throws Exception
	 */
	public static String receive(){
      String message = "";
      
      if (connectionSocket == null)
    	  return message; //or null?
      
	  try
	  {
          BufferedReader receiveObject = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));		          
          message = receiveObject.readLine();
          //receiveObject.close();
      }
	  catch (IOException e) {
		  e.printStackTrace();
		  System.out.println("Connection error (Client crash?)");
	  }
	  
	  return message;
	}
	
	public static String receive2(){
	      String message = "";
	      
	      if (connectionSocket == null)
	    	  return message; //or null?
	      
		  try
		  {
			  
	          BufferedReader receiveObject = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));		          
	          message = receiveObject.readLine();
	          //receiveObject.close();
	      }
		  catch (IOException e) {
			  e.printStackTrace();
			  System.out.println("Connection error (Client crash?)");
		  }
		  
		  return message;
		}
	
	public static String receive(String ipAddress,int port){
		String message = "";
	      
		  //make new connection
		  if (!openConnection(ipAddress,port))
			  return message;
	      
	      if (connectionSocket == null)
	    	  return message;
	      
		  try
		  {
	          BufferedReader receiveObject = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));		          
	          message = receiveObject.readLine();
	          //receiveObject.close();
	      }
		  catch (IOException e) {
			  e.printStackTrace();
			  System.out.println("Connection error (Client crash?)");
		  }
		  
		  return message;
	}
	
	public static Server receiveServer(){
		Server server = null;
	      
	      if (connectionSocket == null)
	    	  return null;
	      
		  try
		  {
			  //InputStream is = connectionSocket.getInputStream();
			  BufferedInputStream is = new BufferedInputStream(connectionSocket.getInputStream());
			  ObjectInputStream ois = new ObjectInputStream(is);
			  server = (Server)ois.readObject();
	      }
		  catch (IOException e) {
		  } catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		  }
		  
		  return server;
	}
	
	/**
	 * Send out a message
	 * @param message
	 */
	public static boolean send(String message){	
		
		 if (connectionSocket == null)
	    	  return false; //
		
		boolean ret = true;
		PrintWriter sendObject = null;
		
		//System.out.println("ClientConnection.send():"+connectionSocket.getInetAddress()+":"+connectionSocket.getPort());
		
		try {
			sendObject = new PrintWriter(connectionSocket.getOutputStream(), true);
			sendObject.println(message);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			ret = false;
		}			
		
		return ret;
	}
	
	public static boolean sendPS(String message){	
		
		 if (connectionSocketPS == null)
	    	  return false; //
		
		boolean ret = true;
		PrintWriter sendObject = null;
		try {
			sendObject = new PrintWriter(connectionSocketPS.getOutputStream(), true);
			sendObject.println(message);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			ret = false;
		}			
		
		return ret;
	}
	
	public static boolean send(String message, Socket soc){	
		
		 if (soc == null)
	    	  return false; //
		
		boolean ret = true;
		PrintWriter sendObject = null;
		try {
			sendObject = new PrintWriter(soc.getOutputStream(), true);
			sendObject.println(message);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			ret = false;
		}			
		
		return ret;
	}
	
	public static boolean sendGameState(Maze game){
		OutputStream os;
		boolean ret = true;
		
		try {
			os = connectionSocket.getOutputStream();
			ObjectOutputStream sendObject = new ObjectOutputStream(os);
			sendObject.writeObject(game);
			//sendObject.close();
			//os.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ret = false;
			//e.printStackTrace();			
		}
		
		return ret;
	}
	
	public static boolean sendGameStatePS(Maze game){
		OutputStream os;
		boolean ret = true;
		
		try {
			os = connectionSocketPS.getOutputStream();
			ObjectOutputStream sendObject = new ObjectOutputStream(os);
			sendObject.writeObject(game);
			//sendObject.close();
			//os.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ret = false;
			//e.printStackTrace();			
		}
		
		return ret;
	}
	
	public static boolean sendGameState(Maze game, Socket soc){
		OutputStream os;
		boolean ret = true;
		
		try {
			os = soc.getOutputStream();
			ObjectOutputStream sendObject = new ObjectOutputStream(os);
			sendObject.writeObject(game);
			//sendObject.close();
			//os.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ret = false;
			//e.printStackTrace();			
		}
		
		return ret;
	}
	
	/**
	 * To close connection of Socket object
	 * @throws Exception
	 */
	public static void closeConnection()
	{
		try {
			connectionSocket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
